package com.jewaton.auth.commons.service;

import com.jewaton.auth.commons.dao.PermissionDAO;
import com.jewaton.auth.commons.dao.RoleDAO;
import com.jewaton.auth.commons.entity.AccountRole;
import com.jewaton.auth.commons.entity.OperateAuth;
import com.jewaton.auth.commons.entity.Permission;
import com.jewaton.auth.commons.entity.Role;
import com.jewaton.auth.commons.util.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.annotation.Resource;
import java.util.Arrays;

public abstract class AbstractRBACService implements RBACService {
    
    private static final Log log = LogFactory.getLog(AbstractRBACService.class);

    @Resource(name="permissionDAO")
    private PermissionDAO permissionDAO;
    @Resource(name="roleDAO")
    private RoleDAO roleDAO;
    
    public void setPermissionDAO(PermissionDAO permissionDAO) {
        this.permissionDAO = permissionDAO;
    }
    public void setRoleDAO(RoleDAO roleDAO) {
        this.roleDAO = roleDAO;
    }
    public PermissionDAO getPermissionDAO() {
        return permissionDAO;
    }
    public RoleDAO getRoleDAO() {
        return roleDAO;
    }
    
    @Override
    public void addRole(Role role) {
        roleDAO.addRole(role);
    }

    
    @Override
    public void addAccountRole(AccountRole accountRole) {
        roleDAO.addAccountRole(accountRole);
    }
    @Override
    public Role findRoleById(long rid) {
        return roleDAO.getRoleById(rid);
    }

    @Override
    public void updateRole(Role role) {
        roleDAO.updateRole(role);
    }

    @Override
    public void updatePermission(Permission permission) {
        permissionDAO.updatePermission(permission);
    }
    @Override
    public void updateOauth(OperateAuth oauth) {
        permissionDAO.updateOauth(oauth);
    }
    
    public void flush() {
        permissionDAO.flush();
    }
    
    @Override
    public void deleteRole(long rid) {
        roleDAO.deleteRole(rid);
    }
    
    @Override
    public void delRoles(String ids) {
        ids = StringUtil.getSQLInValues(ids);
        roleDAO.delRoles(ids);
    }
    @Override
    public void assginRolePermission(String originPermissions, String changePermissions,
            long rid) {
        String[] origin = originPermissions.split("#");
        String[] change = changePermissions.split("#");
        String[] toAddArray = StringUtil.getMinus(change, origin);
        String[] toDelArray = {};
        String toAdd = StringUtil.getArrayString(toAddArray);
        int countAdd = toAddArray.length;
        String toDel = "";
        int countDel = 0;
        
        if(!StringUtil.isBlank(originPermissions)) {
            toDelArray = StringUtil.getMinus(origin, change);
            countDel = toDelArray.length;
            toDel = StringUtil.getArrayString(toDelArray);
        }
        
        int maxInCount = 1000;
        
        if (countDel > 0) {
            if (countDel > maxInCount) {
                log.info("角色id： " + rid + " 要删除的权限id集合个数:" + countDel + " 大于1000个 分批删除");
                int ratio = countDel / maxInCount;
                int mod = countDel % maxInCount;
                log.debug("countDel:" + countDel + " ratio: " + ratio + " mod:" + mod);
                for (int i=0; i<ratio; i++) {
                    String[] subToDelArray = new String[maxInCount];
                    System.arraycopy(toDelArray, i * maxInCount, subToDelArray, 0, maxInCount);
                    deleteRolePermissions(rid, StringUtil.getArrayString(subToDelArray));
                }
                if (mod > 0) {
                    String[] subToDelArray = new String[mod];
                    System.arraycopy(toDelArray, countDel - mod, subToDelArray, 0, mod);
                    deleteRolePermissions(rid, StringUtil.getArrayString(subToDelArray));
                }
            } else {
                if (this.deleteRolePermissions(rid, toDel) != countDel ) {
    //                throw new RuntimeException("角色id： " + rid + " 要删除的权限id集合:" + toDel + "跟实际删除的权限列表不符");
                    log.info("角色id： " + rid + " 要删除的权限id集合:" + toDel + "跟实际删除的权限列表不符");
                }
            }
            
        }
        if (countAdd > 0) {
            if (countAdd > maxInCount) {
                log.info("角色id： " + rid + " 要增加的权限id集合个数:" + countAdd + " 大于1000个 分批增加");
                int ratio = countAdd / maxInCount;
                int mod = countAdd % maxInCount;
                log.debug("countAdd:" + countAdd + " ratio: " + ratio + " mod:" + mod);
                for (int i=0; i<ratio; i++) {
                    String[] subToAddArray = new String[maxInCount];
                    System.arraycopy(toAddArray, i * maxInCount, subToAddArray, 0, maxInCount);
                    addRolePermissions(rid, StringUtil.getArrayString(subToAddArray));
                }
                if (mod > 0) {
                    String[] subToAddArray = new String[mod];
                    System.arraycopy(toAddArray, countAdd - mod, subToAddArray, 0, mod);
                    addRolePermissions(rid, StringUtil.getArrayString(subToAddArray));
                }
            } else {
                if (addRolePermissions(rid, toAdd) != countAdd ) {
    //                throw new RuntimeException("角色id： " + rid + " 要增加的权限id集合:" + toAdd + "跟实际添加的权限列表不符");
                    log.info("角色id： " + rid + " 要增加的权限id集合:" + toAdd + "跟实际添加的权限列表不符");
                }
            }
            
            
        }
    }

    @Override
    public Role findRoleByName(String roleName) {
        return roleDAO.getRoleByName(roleName);
    }
    
    @Override
    public OperateAuth findOAuthById(Long oauthId) {
        return permissionDAO.getOperateAuthById(oauthId);
    }
    
    
    @Override
    public Permission getPermByOauthId(Long oauthId) {
        return permissionDAO.getPermByOauthId(oauthId);
    }
    
    @Override
    public Permission getPermByMenuId(Long menuId) {
        return permissionDAO.getPermByMenuId(menuId);
    }
    private int addRolePermissions(long rid, String permissionValues) {
        permissionValues = StringUtil.getSQLInValues(permissionValues);
        return permissionDAO.addRolePermissions(rid, permissionValues);
    }
    private int deleteRolePermissions(long rid, String permissionValues) {
        permissionValues = StringUtil.getSQLInValues(permissionValues);
        return permissionDAO.deleteRolePermissions(rid, permissionValues);
    }

    public static void main(String[] args) {
//        System.out.println(1500/1000);
//        System.out.println(1500%1000);
        
        int maxInCount = 7;
        int countDel = 21;
        int ratio = countDel / maxInCount;
        int mod = countDel % maxInCount;
        System.out.println("countDel:" + countDel + " ratio: " + ratio + " mod:" + mod);
//        String[] toDelArray = new String[]{"1", "2", "3", "4", "5"};
        String[] toDelArray = new String[countDel];
        for (int i=0; i<countDel; i++) {
            toDelArray[i] = i +"";
        }
        for (int i=0; i<ratio; i++) {
            String[] subToDelArray = new String[maxInCount];
            System.arraycopy(toDelArray, i * maxInCount, subToDelArray, 0, maxInCount);
            System.out.println(i + " " + Arrays.asList(subToDelArray));
        }
        if (mod > 0) {
            String[] subToDelArray = new String[mod];
            System.arraycopy(toDelArray, countDel - mod, subToDelArray, 0, mod);
            System.out.println(Arrays.asList(subToDelArray));
        }
    }
    
}
